<!-- 员工考勤月历用 -->
<template>
  <div ref="timeSliderRef" class="time-slider" :class="{ 'is-down': isDown }" @mousedown="handleMouseDownTimeLine" @mouseup="handleMouseUpTimeLine" @mouseleave="handleMouseLeaveTimeLine">
    <template v-for="(item, idx) in marks">
      <div class="cell" v-if="idx !== marks.length - 1" :class="{ selected: isSelectedCell(item), begin: item.isBegin, end: item.isEnd, rest: item.isRest, rest2: item.isRest2, disabled: item.isDisabled }" @mousedown="handleMouseDownCell(item)" @mouseenter="handleMouseEnterCell(item)" @mouseup="handleMouseUpCell(item)">
        <div class="time">
          <el-popover v-if="item.children && item.children.length > 0" placement="right" :width="700">
            <template #reference>
              <div>
                <div>{{ item.label }}</div>
                <el-tag type="info" round effect="plain" v-if="item.overflow && item.overflow > 0">+{{ item.overflow }}</el-tag>
              </div>
            </template>
            <TimeSliderCellDetail :itemData="item.children" :timelogCategory="timelogCategory" @click-btn-delele="handlerClickBtnDeleteTimeSliderCellDetail" />
          </el-popover>
          <template v-else>{{ item.label }}</template>
        </div>
        <div class="cell-bd">
          <div class="time-slider-cells">
            <template v-for="(item2, idx) in item.children">
              <TimeSliderCell v-if="idx < 3" :itemData="item2" :timelogCategory="timelogCategory" />
            </template>
          </div>
          <div class="btn-group" v-if="item.children.length > 0">
            <div class="btn-cell delete" @click.prevent.stop="handlerClickBtnDelete(item.children)">
              <el-icon><Delete /></el-icon>
            </div>
            <el-button v-if="false" type="primary" size="small" @click.prevent.stop="handlerClickBtnEdit" :icon="Edit"></el-button>
            <el-button v-if="false" type="danger" size="small" @click.prevent.stop="handlerClickBtnDelete" :icon="Delete"></el-button>
          </div>
        </div>
        <div class="red-line start" v-if="item.isBegin" :style="{ top: item.locBegin }"></div>
        <div class="red-line end" v-if="item.isEnd" :style="{ top: item.locEnd }"></div>
        <div class="red-line rest" v-if="item.isRest" :style="{ top: item.locRest }"></div>
        <div class="red-line rest" v-if="item.isRest2" :style="{ top: item.locRest2 }"></div>
      </div>
    </template>
    <div class="line"></div>
  </div>
</template>
<script lang="ts" setup>
import TimeSliderCell from './TimeSliderCell.vue'
import TimeSliderCellDetail from './TimeSliderCellDetail.vue'
import { reactive, ref, onMounted, watch } from 'vue'
import { Delete, Edit } from '@element-plus/icons-vue'
import IProjectTypes from '../../interface/IProjectTypes'
import { useUsersStore } from '../../stores'

const props = defineProps({
  today: {
    type: String || Date,
    required: true,
    default: '',
  },

  timeDates: {
    type: Array,
    required: true,
    default: () => [],
  },
  beginTime: {
    type: String,
    default: '08:00',
  },
  endTime: {
    type: String,
    default: '17:00',
  },
  disabledTimes: {
    type: Array,
    required: true,
    default: () => [],
  },
  logList: {
    type: Array<any>,
    required: true,
  },
  timelogCategory: {
    type: Array<IProjectTypes>,
    required: true,
    default: () => [{ dictCode: 0 }],
  },
})

const emits = defineEmits(['checked', 'deleteCell'])
const usersStore = useUsersStore()
const timeSliderRef = ref<HTMLElement | null>(null)
const isDown = ref(false)

let marks = reactive<any[]>([])
const selectedCell = ref<any[]>([])
const checkMarks = ref<any[]>([])

onMounted(async () => {
  // console.log('！===== onMounted', props.logList)
  initMarks()
  updateMarks()
  // console.log('！===== onMounted marks', marks)
})
watch(
  () => props.logList,
  () => {
    // console.log('！===== watch', props.logList)
    initMarks()
    updateMarks()
    // console.log('！===== watch marks', marks)
    // props.logList.forEach((item: any) => {
    //   item.startTime.slice(0, -2)
    //   item.endTime.slice(0, -2)
    // })

    // startTime
    // endTime
    // const cell = props.logList.find((e) => {
    //   const str1 = e.startTime.slice(0, -2)
    //   const str2 = item.value.slice(0, -2)
    //   return str1 == `${props.today} ${str2}`
    // })
  }
)
/**
 * 更新标记状态
 *
 * 根据当前日志列表和今天的时间，更新标记数组marks的状态。
 * 对于marks数组中的每一个元素，会筛选出日志列表中开始时间（不包含秒数）与当前时间和标记时间（不包含秒数）一致的日志条目，
 * 并将这些日志条目作为子元素赋值给当前元素的children属性。
 * 同时，设置当前元素的active属性为false，isDisabled属性根据子元素的长度决定（如果有子元素则为true，否则为false），
 * 如果子元素长度大于3，则设置overflow属性为子元素长度减去3的值，否则不设置overflow属性。
 */
const updateMarks = () => {
  // console.log('updateMarks')
  marks.map((item: any) => {
    const cells = props.logList.filter((e) => e.startTime.slice(0, -2) === props.today + ' ' + item.value.slice(0, -2))
    item.children = cells
    item.active = false
    item.isDisabled = cells.length > 0
    if (cells.length > 0) {
      item.overflow = cells.length - 3
    }
  })
}
/**
 * 初始化标记
 *
 * 该函数用于初始化marks数组，将timeDates数组中的每个元素转换为对象并推入marks数组中
 *
 * @returns 无返回值
 */
const initMarks = () => {
  // console.log('initMarks')
  let i = 0
  marks = []
  const { startLunchTime, endLunchTime } = usersStore.getAllState() as any
  const hasBegin = props.timeDates.indexOf(props.beginTime)
  const hasEnd = props.timeDates.indexOf(props.endTime)
  const hasRest = props.timeDates.indexOf(startLunchTime)
  const hasRest2 = props.timeDates.indexOf(endLunchTime)
  props.timeDates.forEach((item: any) => {
    const idx = props.disabledTimes.findIndex((e) => e == item)
    let isBegin = props.beginTime == item
    let isEnd = props.endTime == item
    let locBegin = '0'
    let locEnd = '0'
    let isRest = false
    let locRest = '0'
    let isRest2 = false
    let locRest2 = '0'

    if (hasRest == -1 && item.slice(0, 2) === startLunchTime.slice(0, 2)) {
      locRest = (parseInt(startLunchTime.slice(-2)) / 60) * 100 + '%'
      isRest = true
    } else if (hasRest > -1 && item.slice(0, 2) === startLunchTime.slice(0, 2)) {
      locRest = '0%'
      isRest = true
    }
    if (hasRest2 == -1 && item.slice(0, 2) === endLunchTime.slice(0, 2)) {
      locRest2 = (parseInt(endLunchTime.slice(-2)) / 60) * 100 + '%'
      isRest2 = true
    } else if (hasRest2 > -1 && item.slice(0, 2) === endLunchTime.slice(0, 2)) {
      locRest = '0%'
      isRest = true
    }

    if (hasBegin == -1 && item.slice(0, 2) === props.beginTime.slice(0, 2)) {
      isBegin = true
      locBegin = (parseInt(props.beginTime.slice(-2)) / 60) * 100 + '%'
    }

    if (hasEnd == -1 && item.slice(0, 2) === props.endTime.slice(0, 2)) {
      isEnd = true
      locEnd = (parseInt(props.endTime.slice(-2)) / 60) * 100 + '%'
    }
    // if (props.beginTime == '08:00') {
    //   // startWorkTime
    //   // 长春
    //   isEnd = item == '16:00'
    //   locEnd = '83.3%'
    // } else if (props.beginTime == '09:00') {
    //   // 北京
    // }
    marks.push({ id: i, label: item, active: false, value: item, isDisabled: idx > -1, isBegin, isEnd, locBegin, locEnd, isRest, locRest, locRest2, isRest2 })
    i++
  })
  // console.log('startWorkTime', startWorkTime)
  // console.log('endWorkTime', endWorkTime)
  // console.log('hasBegin', hasBegin)
  // console.log('hasEnd', hasEnd)
  // console.log('marks', marks)
}
/**
 * 处理时间轴上的鼠标按下事件
 *
 * @returns 无返回值
 */
const handleMouseDownTimeLine = () => {
  // isDown.value = true
}
/**
 * 处理时间线鼠标抬起事件
 *
 * 当鼠标在时间线上抬起时，将isDown的值设置为false
 */
const handleMouseUpTimeLine = () => {
  // isDown.value = false
}
/**
 * 处理鼠标离开时间线时的行为
 *
 * 当鼠标离开时间线时，将isDown的值设置为false，表示当前不是按下状态。
 */
const handleMouseLeaveTimeLine = () => {
  // isDown.value = false
}
/**
 * 检查单元格是否被选中
 *
 * @param item 单元格数据对象
 */
const checkedCell = (item: any) => {
  if (isDown.value) {
    item.active = true
    // getTimeCell(item)
  }
}
const getTimeCell = (item: any) => {
  // isDown.value = false
  marks.map((e) => {
    e.active = false
  })
  // checkMarks.value.push(item)
  let idxStart = marks.findIndex((e) => e.label === checkMarks.value[0].label)
  let idxEnd = marks.findIndex((e) => e.label === item.label)
  // const idxEnd2 = marks.findIndex((e) => !e.isDisabled)
  if (idxStart > idxEnd) {
    const tempIdx = idxStart
    idxStart = idxEnd
    idxEnd = tempIdx
  }
  const tempArr = marks.slice(idxStart, idxEnd + 2)
  const flag = idxStart === idxEnd && item.isDisabled
  // 创建 input 元素
  let inputElement = document.createElement('input')
  inputElement.type = 'text'
  inputElement.setAttribute('style', 'position: absolute; top: 0; left: 0; width: 100%; height: 100%; opacity: 0; z-index: -1')
  document.body.appendChild(inputElement)
  // 使 input 元素获得焦点
  inputElement.focus()
  // 延迟一段时间后销毁 input 元素
  setTimeout(() => {
    inputElement.remove()
  }, 2000)
  console.log('tempArr', tempArr)
  if (tempArr.length > 1) {
    // console.log(' ======= 0', tempArr)
    const tempArr2 = filterConsecutiveElements(tempArr)
    // console.log('idxStart', idxStart, checkMarks.value[0])
    // console.log('idxEnd', idxEnd, item)
    // console.log('idxEnd2', idxEnd2)
    // console.log('tempArr', JSON.stringify(tempArr))
    // console.log('tempArr2', JSON.stringify(tempArr2))
    if (tempArr2) {
      // console.log(' ======= tempArr2', tempArr2)
      // console.log('[]', res)
      let res = [tempArr2.shift(), tempArr2.pop()]
      if (flag) {
        // console.log(' ======= 000', item)
        if (item.isDisabled === false) {
          res = [item, marks[idxEnd + 1]]
          // console.log(' ======= 11111', item)
          emits('checked', res)
        } else {
          clearSelectedCell()
        }
      } else {
        // console.log('[]', res)
        // console.log(' ======= 1', item)
        emits('checked', res)
      }
    } else {
      clearSelectedCell()
    }
  } else if (tempArr.length == 1) {
    // console.log(' ======= 2', item)
    if (item.isDisabled === false) {
      emits('checked', [item, marks[idxEnd + 1]])
      // console.log('[item]', [item, marks[idxEnd + 1]])
      // console.log('[item]', [item, item])
    } else {
      clearSelectedCell()
    }
  } else {
    // return false
  }
}
/**
 * 将给定数组中连续的、未禁用的元素组合成子数组，并返回这些子数组的数组。
 *
 * @param arr 包含多个元素的数组，每个元素都具有 isDisabled 属性。
 * @returns 包含多个子数组的数组，每个子数组包含连续的、未禁用的元素。
 */
const filterConsecutiveElements = (list: any[]) => {
  const result = []
  let currentGroup: any[] = []
  console.log('没了 ', list)
  list.forEach((item) => {
    if (item.isDisabled) {
      if (currentGroup.length > 0) {
        currentGroup.push(item)
        result.push(currentGroup)
      }
      currentGroup = []
    } else {
      currentGroup.push(item)
    }
  })

  if (currentGroup.length > 0) {
    result.push(currentGroup)
  }
  console.log('没了 result ', result)
  if (result.length > 0) {
    const res = [result[0].shift(), result[0].pop()]
    return res
  } else {
    return null
  }

  // if (!tempItem.isDisabled) {
  //   const idx = arr.findIndex((item: any) => {
  //     return item.isDisabled == true
  //   })
  //   const nn = arr.splice(0, idx + 1)
  //   console.log('idx', idx)
  //   console.log('nn', nn)
  // }
  // for (let item of arr) {
  //   console.log('111 item', item)
  //   if (item.isDisabled === false) {
  //     if (!started) {
  //       started = true
  //     }
  //     consecutiveElements.push(item)
  //   } else {
  //     if (started && consecutiveElements.length > 0) {
  //       console.log('222')
  //       myArr.push(consecutiveElements)
  //     }
  //     consecutiveElements = []
  //     started = false
  //   }
  // }
  // if (started && consecutiveElements.length > 0) {
  //   console.log('111')
  //   myArr.push(consecutiveElements)
  // }
  // return myArr
}

/**
 * 处理鼠标按下单元格事件
 *
 * @param item 当前选中的单元格对象
 */
const handleMouseDownCell = (item: any) => {
  console.log('handleMouseDownCell', item)
  isDown.value = true
  checkMarks.value = [item]
  selectedCell.value.push(item)
  checkedCell(item)
}
/**
 * 处理鼠标在单元格上松开的事件
 *
 * @param item 单元格数据对象
 */
const handleMouseUpCell = (item: any) => {
  if (isDown.value == true) {
    selectedCell.value.push(item)
    getTimeCell(item)
  }
}
/**
 * 当鼠标进入单元格时触发的函数
 *
 * @param item 当前单元格的数据
 */
const handleMouseEnterCell = (item: any) => {
  // console.log('handleMouseEnterCell', item)
  if (isDown.value == true) {
    selectedCell.value.push(item)
  }
}

const isSelectedCell = (item: any) => {
  const idx = selectedCell.value.findIndex((e) => e.label == item.label)
  return idx > -1
}

const clearSelectedCell = () => {
  selectedCell.value = []
  isDown.value = false
}
const handlerClickBtnEdit = () => {}
const handlerClickBtnDelete = (children: any) => {
  const ids: any[] = []
  children.forEach((e: any) => {
    ids.push(e.id)
  })
  emits('deleteCell', ids)
}

const handlerClickBtnDeleteTimeSliderCellDetail = (id: number) => {
  emits('deleteCell', [id], 'byId')
}

defineExpose({ clearSelectedCell })
</script>
<style scoped lang="scss">
.time-slider {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  border-bottom: 1px solid #e4e7ed;
  &.is-down {
    .cell {
      &:after {
        opacity: 1;
        display: block;
      }
      &:hover {
        background-color: rgba(0, 0, 0, 0);
      }
      &.selected {
        // background-color: #337ecc;
        &:after {
          opacity: 0;
          display: none;
        }
      }
    }
  }
  .cell {
    display: flex;
    flex: 1;
    border-top: 1px solid #e4e7ed;
    align-items: self-start;
    position: relative;
    background-color: #fff;
    &:after {
      content: '';
      opacity: 0;
      display: none;
      position: absolute;
      pointer-events: none;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background-color: rgba(0, 0, 0, 0.2);
    }

    &.checked {
      background-color: #337ecc;
    }
    &.begin,
    &.end,
    &.rest,
    &.rest2 {
      .red-line {
        display: block;
      }
      // border-top: 2px solid #ff0000;
    }
    &.disabled {
      color: #337ecc;
      background-color: #ecf5ff;
      &:hover {
        background-color: #ecf5ff;
      }
    }
    &.selected {
      // background-color: #337ecc;
      &:after {
        opacity: 0;
        display: none;
      }
    }
    .red-line {
      display: none;
      pointer-events: none;
      position: absolute;
      right: 0;
      left: 0;
      height: 2px;
      background-color: #c45656;
      &.rest,
      &.rest2 {
        background-color: transparent;
        height: 0px;
        // border-style: dotted;
        border-bottom: 1px dashed rgb(248, 152.1, 152.1);
        border-bottom-style: dashed;
      }
    }
    .time {
      width: 60px;
      user-select: none;
    }
    .cell-bd {
      display: flex;
      flex: 1;
      height: 100%;
      // pointer-events: none;
      overflow: hidden;
      .time-slider-cells {
        flex: 1;
        text-align: left;
        padding: 0 10px;
        font-size: 14px;
      }
      .btn-group {
        justify-content: center;
        align-items: center;
        display: flex;
        transform: translate(100%, 0);
        transition: transform 0.1s linear 0.2s;
        .btn-cell {
          width: 70px;
          background-color: #f56c6c;
          color: #fff;
          height: 100%;
          font-size: 24px;
          display: flex;
          justify-content: center;
          align-items: center;
        }
      }
      &:hover {
        .btn-group {
          transform: translate(0, 0);
          .btn-cell {
          }
        }
      }
    }
    &:last-child {
    }
  }

  .line {
    position: absolute;
    left: 60px;
    top: 0;
    bottom: 0%;
    border-left: 1px solid #e4e7ed;
    pointer-events: none;
  }
  .work-line {
    position: absolute;
    width: 100%;
    height: 0;
    left: 0;
    opacity: 0.5;
    pointer-events: none;
    border-bottom: 1px dashed rgba(255, 0, 0, 0.5);

    &.begin {
      top: 10%;
    }
    &.end {
      top: 70%;
    }
    &.job {
      top: 55%;
      border-bottom: 2px solid rgba(255, 0, 0, 1);
    }
  }
}
</style>
